package com.jh.paymentchannel.service;

import cn.jh.common.exception.ServiceException;
import cn.jh.common.utils.CommonConstants;
import cn.jh.common.utils.CommonsUtil;
import com.jh.paymentchannel.business.CongMingPayBusiness;
import com.jh.paymentchannel.util.Util;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.net.URI;
import java.util.List;
import java.util.Map;

/**
 * 快银支付：POS机
 */
@RestController
public class CongMingPayService {

    private static final Logger log = LoggerFactory.getLogger(CongMingPayService.class);

    @Autowired
    private Util util;
    private final CongMingPayBusiness congMingPayBusiness;

    @Autowired
    public CongMingPayService(CongMingPayBusiness congMingPayBusiness) {
        this.congMingPayBusiness = congMingPayBusiness;
    }

    /**
     * 公众号支付
     * @param shopId
     * @param money
     * @return
     */
    @PostMapping(value = "/v1.0/paymentchannel/congmingpay/buypay")
    public Object toBuyPay(String shopId, BigDecimal money) {
        try {
            if (money.compareTo(BigDecimal.ZERO) < 0) {
                return CommonsUtil.returnError("交易金额必须大于0.00元！");
            }
            // 1、验证商户信息
            getShopRegister(shopId);
            // 2、进行公众号支付
            Map<String, Object> res = congMingPayBusiness.toBuyPay(shopId, money);
            // TODO 返回值处理--未完成
            return null;
        } catch (ServiceException r) {
            r.printStackTrace();
            return CommonsUtil.returnError(r.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return CommonsUtil.returnError("服务器异常，请稍后再试！");
        }
    }

    /**
     * 预支付接口用于提前获取需要支付的金额，客户扫描二维码即完成支付：反扫描
     * 响应内容为字符串形式，将字符串生成二维码，既可以完成支付。
     * @param shopId 开店管家shopId
     * @param money 交易金额
     * @param payType 支付类型：微信-weixin，支付宝-alipay
     * @return
     */
    @PostMapping(value = "/v1.0/paymentchannel/congmingpay/prepay")
    public Object prePay(String shopId, BigDecimal money,
                         @RequestParam(value = "payType", defaultValue = "", required = false) String payType) {
        try {
            if (money.compareTo(BigDecimal.ZERO) < 0) {
                return CommonsUtil.returnError("交易金额必须大于0.00元！");
            }
            // 1、验证商户信息
            getShopRegister(shopId);
            // 2、进行预支付
            List<Map<String, Object>> list = congMingPayBusiness.prePay(shopId, money, payType);
            return CommonsUtil.returnSuccess("预支付成功！", list);
        } catch (ServiceException e) {
            e.printStackTrace();
            return CommonsUtil.returnError(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return CommonsUtil.returnError("服务器异常，请稍后再试！");
        }
    }

    /**
     * 验证商户信息
     * @param shopId
     * @return
     */
    private void getShopRegister(String shopId) throws ServiceException {
        URI uri = util.getServiceUrl("user", "error url requset!");
        String url = uri + "/v1.0/user/shops/query/getShopByShopId";

        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("shopId", shopId);

        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.postForObject(url, body, String.class);
        JSONObject jsonObject = JSONObject.fromObject(result);

        String respCode = jsonObject.getString(CommonConstants.RESP_CODE);
        String respMsg = jsonObject.getString(CommonConstants.RESP_MESSAGE);
        if (!CommonConstants.SUCCESS.equals(respCode)) {
            throw new ServiceException(respMsg);
        }
    }

    /**
     * 条码支付接口
     * 条码支付接口用于商户使用扫码枪等扫码工具扫描客户手机付款吗，从而实现支付功能：主扫码
     * @param shopId 商户id，此shopId为快银通道方生成的，请区别本项目中的shopId
     * @param money 交易金额
     * @param authCode 支付授权码：用户微信中的首付款条形码
     * @return
     */
    @PostMapping(value = "/v1.0/paymentchannel/congmingpay/micropay")
    public Object toMicroPay(String shopId, BigDecimal money, String authCode) {
        try {
            if (money.compareTo(BigDecimal.ZERO) < 0) {
                return CommonsUtil.returnError("交易金额必须大于0.00元！");
            }
            // 1、验证商户信息
            getShopRegister(shopId);
            // 2、进行条码支付
            Map<String, Object> map = congMingPayBusiness.toMicroPay(shopId, money, authCode);
            // TODO 返回值处理
            return CommonsUtil.returnSuccess("支付成功！", map);
        } catch (ServiceException e) {
            e.printStackTrace();
            return CommonsUtil.returnError(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return CommonsUtil.returnError("服务器异常，请稍后再试！");
        }
    }

    /**
     * 预支付成功回调地址
     * @param resultCode SUCCESS/FAIL
     * @param resultMsg 支付失败时返回失败原因
     * @param congMingShopId 商户id：有注册完成后的真实id经过MD5生成
     * @param money 支付金额，保留两位小数
     * @param type 支付方式：weixin/alipay
     * @param timeEnd 支付成功时间：yyyyMMddHHmmss
     * @param orderId 订单号
     * @param outTradeNo 快银订单号
     * @param sign 加密sign
     * @return
     */
    @GetMapping(value = "/v1.0/paymentchannel/congmingpay/prepayredirecturl")
    public void prePayRedirectUrl(HttpServletRequest request,
                                  @RequestParam("result_code") String resultCode,
                                  @RequestParam(value = "result_msg", defaultValue = "", required = false) String resultMsg,
                                  @RequestParam("shopId") String congMingShopId,
                                  @RequestParam("money") BigDecimal money,
                                  @RequestParam(value = "type", defaultValue = "", required = false) String type,
                                  @RequestParam(value = "timeEnd") String timeEnd,
                                  @RequestParam("orderId") String orderId,
                                  @RequestParam("out_trade_no") String outTradeNo,
                                  @RequestParam("sign") String sign) {
        log.info("预支付成功回调地址，result_code = {}，result_msg = {}，shopId = {}，money = {}，type = {}，timeEnd = {}，orderId = {}，out_trade_no = {}，sign = {}",
                resultCode, resultMsg, congMingShopId, money, type, timeEnd, orderId, outTradeNo, sign);
        Map<String, String[]> parameterMap = request.getParameterMap();
        log.info("预支付成功回调地址，parameterMap = {}", parameterMap.toString());
        congMingPayBusiness.prePayRedirectUrl(resultCode, resultMsg, congMingShopId, money, type, timeEnd, orderId, outTradeNo, sign);
    }

    /**
     * 条码扫码查询交易结果
     * @param shopId 商户id
     * @param orderId 订单号
     * @return
     */
    @PostMapping(value = "/v1.0/paymentchannel/congmingpay/querypay")
    public @ResponseBody Object queryPay(String shopId, String orderId) {
        try {
            if (StringUtils.isEmpty(orderId)) {
                return CommonsUtil.returnError("请输入订单号！");
            }
            // 1、验证shopId
            getShopRegister(shopId);
            // 2、查询
            Map<String, Object> map = congMingPayBusiness.queryPay(shopId, orderId);
            return CommonsUtil.returnSuccess("订单查询成功！", map);
        } catch (ServiceException e) {
            e.printStackTrace();
            return CommonsUtil.returnError(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return CommonsUtil.returnError("服务器异常，请稍后再试！");
        }
    }
}
